-- converts a position in pixels to string index
function Font:get_index(sz, pos)
  local w = self:get_width(sz)
  local len = string.len(sz)
  for i = len, 1, -1 do
    local b = string.byte(sz, i)
    local c = string.char(b)
    local cw = self:get_width(c)
    w = w - cw
    if pos > w + cw / 2 then
      return i
    end
  end
  return 0
end

-- converts string index to position in pixels
function Font:get_position(sz, index)
  local sub = string.sub(sz, 1, index)
  return self:get_width(sz)
end

-- clamps a string so that it fits a given width
function Font:clamp(sz, width, postfix)
  if self:get_width(sz) <= width then
    return sz
  end
  postfix = postfix or ""
  if self:get_width(postfix)>= width then
    return ""
  end
  local out = sz
  local len = string.len(sz)
  while true do
    local w = self:get_width(out .. postfix)
    if w > width then
      len = len - 1
      out = string.sub(out, 0, len)
    else
      break
    end
  end
  return out .. postfix
end

-- wraps a string (todo: could be simplified)
function Font:wrap(text, width)
  local lines = {}
  local s = 1
  local e = string.len(text) + 1
  while s < e do
    local out = ''
    local le = s
    while le < e do
      local b = string.byte(text, le)
      local c = string.char(b)
      out = out .. c
      if c == '\n' or c == '\r' then
        break
      end
      if self:get_width(out) >= width then
        break
      end
      le = le + 1
    end
    if le < e then
      local temp = string.reverse(out)
      local space = string.find(temp, '%s')
      if space then
        out = string.sub(text, s, le - space + 1)
      end
    end
    s = s + string.len(out)
    table.insert(lines, out)
  end
  return lines
end